package dk.eclipse.android.badassapp.mission;

import java.text.MessageFormat;
import java.util.Locale;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Window;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import dk.eclipse.android.badassapp.R;
import dk.eclipse.android.badassapp.camera.IntelligenceActivity;
import dk.eclipse.android.badassapp.directions.DirectionsActivity;
import dk.eclipse.android.badassapp.directions.MyLocation;
import dk.eclipse.android.badassapp.directions.MyLocation.LocationResult;
import dk.eclipse.android.badassapp.preferences.PreferenceActivity;
import dk.eclipse.android.badassapp.preferences.PreferenceHelper;

/**
 * This class presents the user interface for the mission tab.
 * 
 * @author Ronni Kahalani (eclipse.dk)
 * 
 */
public class MissionActivity extends Activity {
	private static final String COMMAND_JSI = "commandJSI";
	private static final String HTML_FILE_MISSION = "file:///android_asset/html/mission.html";

	private static final String FORMAT_MAP_STREETVIEW = "google.streetview:cbll={0},{1}&cbp=1,99.56,,1,-5.27&mz=21";
	private static final String FORMAT_MAP_GEO = "geo:{0},{1}";

	private static final int REQCODE_MAP = 1000;
	private static final int REQCODE_STREETVIEW = 1001;
	/**
	 * Tag used for logging information.
	 */
	private static final String LOG_TAG = MissionActivity.class
			.getSimpleName();
	/**
	 * Handles any posting of runnable's to the UI thread
	 */
	private Handler mHandler = new Handler();
	/**
	 * The web browser view.
	 */
	private WebView webView = null;

	private double myLatitude;
	private double myLongitude;
	private double targetLatitude;
	private double targetLongitude;

	// Kapelvej 42 (55.686742199546664, 12.551450729370117)
	static double targetLocationLatitude = 55.686742199546664;
	static double targetLocationLongitude = 12.551450729370117;

	final CharSequence[] items = { "Show Map", "Show StreetView" };

	MyLocation myLocation = null;
	public LocationResult locationResult = new LocationResult() {

		@Override
		public void gotLocation(final Location location) {

			if (location == null) {
				myLatitude = PreferenceHelper
						.getMyLatitude(MissionActivity.this);
				myLongitude = PreferenceHelper
						.getMyLongitude(MissionActivity.this);
			} else {
				myLatitude = location.getLatitude();
				myLongitude = location.getLongitude();
				PreferenceHelper.setMyLocation(MissionActivity.this,
						myLatitude, myLongitude);
			}
			if (webView != null) {
				updateLocation(myLatitude, myLongitude);
			}
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		requestWindowFeature(Window.FEATURE_LEFT_ICON);
		setContentView(R.layout.tab_mission);
		setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
				R.drawable.ic_app);

		webView = (WebView) findViewById(R.id.webview);
		webView.addJavascriptInterface(new CommandJSInterface(), COMMAND_JSI);
		webView.setBackgroundColor(Color.BLACK);
		webView.setWebChromeClient(new MyWebChromeClient());

		webView.setWebViewClient(new WebViewClient() {

			@Override
			public void onPageFinished(WebView view, String url) {

				myLocation = new MyLocation();
				myLocation.getLocation(MissionActivity.this, locationResult);
				super.onPageFinished(view, url);
			}

			public void onReceivedError(WebView view, int errorCode,
					String description, String failingUrl) {
				Toast.makeText(MissionActivity.this,
						"Oh no! " + description, Toast.LENGTH_SHORT).show();
			}
		});

		WebSettings settings = webView.getSettings();
		settings.setJavaScriptEnabled(true);
		settings.setAllowFileAccess(true);
		settings.setBuiltInZoomControls(true);
		settings.setSavePassword(false);
		settings.setSaveFormData(false);
		settings.setSupportZoom(true);
		settings.setJavaScriptCanOpenWindowsAutomatically(true);

		webView.loadUrl(HTML_FILE_MISSION);

		myLatitude = PreferenceHelper.getMyLatitude(this);
		myLongitude = PreferenceHelper.getMyLongitude(this);

		targetLatitude = PreferenceHelper.getTargetLatitude(this);
		targetLongitude = PreferenceHelper.getTargetLongitude(this);

		updateLocation(myLatitude, myLongitude);
	}

	/**
	 * Updates the current location on the web page and builds a javascript call
	 * sting and parse it to the web view.
	 * 
	 * @param location
	 */
	private void updateLocation(double latitude, double longitude) {

		PreferenceHelper.setMyLocation(getApplicationContext(), latitude,
				longitude);

		// Make Javascript call to notify the html page
		// Assure to keep the right decimal number format. We need '.' as the
		// decimal point char ex. 10.5
		// In the Danish number format the comma ',' is the decimal point char.
		String jsCall = String.format(Locale.US,
				"javascript:locationUpdate(%f, %f, %f, %f)", latitude,
				longitude, targetLatitude, targetLongitude);

		webView.loadUrl(jsCall);
	}

	/**
	 * Provides a hook for calling "alert" from javascript. Useful for debugging
	 * your javascript.
	 */
	final class MyWebChromeClient extends WebChromeClient {
		/**
		 * Tag used for logging information.
		 */
		private final String LOG_TAG = MyWebChromeClient.class.getSimpleName();

		@Override
		public boolean onJsAlert(WebView view, String url, String message,
				JsResult result) {
			Log.d(LOG_TAG, message);
			result.confirm();
			return true;
		}

		@Override
		public void onProgressChanged(WebView view, int newProgress) {
			MissionActivity.this.setProgress(newProgress * 1000);
		}
	}

	/**
	 * This class is a javascript interface, used by the web page to call java
	 * code inside this activity.
	 * 
	 * @author Ronni Kahalani (eclipse.dk)
	 * 
	 */
	final class CommandJSInterface {

		CommandJSInterface() {
		}

		public double getMyLatitude() {
			return (myLatitude);
		}

		public double getMyLongitude() {
			return (myLongitude);
		}

		public double getTargetLatitude() {
			return (targetLatitude);
		}

		public double getTargetLongitude() {
			return (targetLongitude);
		}

		/**
		 * Activates a YouTube video, containing a mision briefing.
		 */
		public void missionBriefing() {
			mHandler.post(new Runnable() {
				public void run() {

					Intent intent = new Intent(Intent.ACTION_VIEW);
					intent
							.setData(Uri
									.parse("http://www.youtube.com/watch?v=OBHhMz3wMuc"));
					intent.setClassName("com.google.android.youtube",
							"com.google.android.youtube.PlayerActivity");
					startActivity(intent);

				}
			});
		}

		/**
		 * Start the intelligence activity.
		 */
		public void intelligence() {
			mHandler.post(new Runnable() {
				public void run() {

					Intent intent = new Intent(getApplicationContext(),
							IntelligenceActivity.class);
					startActivity(intent);
				}
			});

		}

		/**
		 * Shows my maps.
		 */
		public void myMaps() {
			mHandler.post(new Runnable() {
				public void run() {

					handleGotoDialog("My Position", items, myLatitude,
							myLongitude);
				}
			});

		}

		/**
		 * Shows target maps.
		 */
		public void targetMaps() {
			mHandler.post(new Runnable() {
				public void run() {
					handleGotoDialog("Target Position", items, targetLatitude,
							targetLongitude);
				}
			});
		}
	}

	/**
	 * Handles the presentation and action in regards to location and map selection.
	 * 
	 * @param title
	 * @param items
	 * @param latitude
	 * @param longitude
	 */
	private void handleGotoDialog(String title, CharSequence[] items,
			final double latitude, final double longitude) {
		AlertDialog.Builder builder = new AlertDialog.Builder(
				MissionActivity.this);
		builder.setTitle(title);

		builder.setItems(items, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int item) {
				handlePositionSelection(item, latitude, longitude);
			}

		});

		AlertDialog alert = builder.create();
		alert.show();

	}

	/**
	 * Handles target position.
	 * 
	 * @param item
	 */
	private void handlePositionSelection(int item, double latitude,
			double longitude) {
		String uri = null;

		// Assure to keep the right decimal number format. We need '.' as the
		// decimal point char ex. 10.5
		// In the Danish number format the comma ',' is the decimal point char.
		Locale.setDefault(Locale.US);

		switch (item) {
		default:
		case 0:
			uri = MessageFormat.format(FORMAT_MAP_GEO, latitude, longitude);
			break;

		case 1:
			uri = MessageFormat.format(FORMAT_MAP_STREETVIEW, latitude,
					longitude);
			break;
		}

		if (uri == null) {
			return;
		}

		// Start the map activity.
		Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri
				.parse(uri));

		// Let's listen for the results of our calls to the MAP activities
		startActivityForResult(intent, (item == 1) ? REQCODE_STREETVIEW
				: REQCODE_MAP);

	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {

		if (resultCode != RESULT_OK) {
			Log.i(LOG_TAG, "Activity result: " + resultCode);
		}

	}

}